查看原文
其他

谈一谈Android应用架构的发展简史

门心叼龙 郭霖 2020-10-29


/   今日科技快讯   /


近日,华为创始人任正非与两位美国互联网思想家尼古拉斯·尼葛洛庞帝、乔治·吉尔德在华为总部深圳进行了深度对谈。 在谈到“美国不给华为提供相关设备”话题时,任正非表示一直以来美国公司都是富有良心的,这次的事件不是发自他们的本心,而是被迫的。 “但是,我们没有想到,美国打击我们华为的决心如此之大,范围之广;但是这些阻扰不了我们前进的步伐。”


/   作者简介   /


本篇文章来自门心叼龙的投稿,分享了他对Android移动应用架构发展简史的理解,相信会对大家有所帮助!同时也感谢作者贡献的精彩文章。


门心叼龙的博客地址:

https://blog.csdn.net/geduo_83


/   项目架构的重要性   /


忙了将近两个月,也算告一段落,一直打算写一篇关于项目架构方面的文章,也是对这段时间工作的一个归纳总结,正好清明节放了三天假,难得有时间…


好了,我们言归正传,我们在前面几篇文章谈到了一些项目架构的问题,年前写了一篇“Android组件化最佳实践”,年后写了一篇“浅谈单一结构体项目的组件化改造”,我们提到了单一结构项目里,结构混乱,层次不清,有些模块同一功能解决方案不统一、有了新需求只是在原有项目上不断的砌代码罢了。长此以往,整个项目就是铁板一块,为后期的项目维护和扩展造成了极大的困难。


我们在软件开发的时候,在做一个项目之前,架构师做工作就是搭项目框架,这是一个前提工作,给整个项目制定开发标准,开发规范,如果没有规范,项目可以搞起来吗?当然可以,就是个开发人员各行其是,最后的结果就是,项目做完了,整个项目结构混乱,层次不清。反之,一旦形成自己的一套框架体系,就可以长期使用,甚至成为整个公司的一套开发标准,大大提高后期的项目开发效率,来了新项目就直接可以在新项目中使用,而把主要的精力放在业务功能的实现上。


/   架构的变   /


前阵子在一个技术群里面,有人说他们现在还用的是传统的架构MVC的架构,觉得挺好,甚至还在用ListView,我只能说,你感觉良好就行,有这种情况吗?肯定有,以前的一些老技术,老方案,能实现吗?当然可以,可以实现具体的开发要求,就好比你去理发店理发,你进店之后,前台就会问你,你要找那个老师给你理?


我们这里有20块的,也有50块,最高是200块的,问你要选一种?20块也能做,200块也能做,价格却整整差了10倍,为什么?这就是不同老师他们水平不一样,做法不一样罢了,你20元有20元的做法,你200元当然有200元的做法,我们做软件开发也一样,同一个项目,你给两千元有两千架构的做法,你给二十万也有二十万元的架构的做法,最终功能都能实现,只是软件质量不同罢了。


/   架构的不变   /


在后移动时代我的一些思考的这篇文章里,我们谈到这是一个知识爆炸的时代,尤其是做技术这一行业的,不像一些传统的行业,例如医生、律师这些知识结构相对稳定的行业,做技术的我们时常会深深的体会到技术更新换代太快了,我们一项新技术还没有研究透彻,就又有新的技术来替代它了,但是不管技术怎么变,但是永远不变的一个核心思想就是“调用更加方便、更加安全、代码之间的耦合度更低”,这是一个好的软件永远追求的目标。


/   代码质量问题  /


同样的一个功能初级工程师能实现吗?可以,高级工程师可以做吗?当然也可以,有何不同?可能高级工程师1个小时就能实现的功能,作为一个初级工程师可能需要1天时间才能完成,一个高级工程师可能需要50行代码实现的问题,初级工程师可能花了两三百行才能搞定,高级工程师实现的功能bug率很低,而初级工程师可能一测试到处都是bug,这就是区别,这就是软件的质量不同。


当然,在实际工作当中有很多时候,项目需要赶进度,领导看的是结果,就看你功能实现了没有?你没有办法,只能选择做20元了,因为你想要做好,你就需要花更多的时间了,而现在没有人给你这个时间去做这个工作。


/   代码简洁之道  /


在唐代有一位大诗人叫白居易,他每作一首诗,都要给不识字的老太太念念,老太太能听懂的,就要,听不大懂的,就改,这也是为什么他的诗一直在民间广为流传,而且还流传到了日本,而我们写代码也是一样的道理,越简单也好。


我曾经看过别人写的一个关于app应用市场下载的功能,一个简单的功能搞了十几个类,各个类之间层次不清,引用关系混乱,实在让人看不下去,一个好的工程师,不在于你写了多么复杂的功能,而在于你写了一个多么好的功能,代码简洁,结构清晰,人人都能看懂,这才是好代码,反对臃肿,真正的做到了简约而不简单,这才是编码高手。


/   Android应用架构发展史  /


一代MVC架构:


  • Model: 用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法

  • View: 渲染页面

  • Controller: 控制器,他是M和V之间的连接器,处理相关的业务逻辑

  • 标准的MVC架构它的工作流程:


View接受用户的交互请求


  1. View将请求转交给Controller

  2. Controller操作Model进行数据更新

  3. 数据更新之后,Model通知View数据变化

  4. View显示更新之后的数据


MVC工作流程图:



在最早从事android开发这批人员,最早使用的是都是MVC架构,这是一种非标准的MVC架构,因为Activity及承担Controller的角色,又承担了View的角色。Activity 和 Fragment 越来越多的同时承担了 Controller 和 View 的职责,导致他们变得及其臃肿且难以维护,由于 Controller 和 View 的揉合,回调嵌套太多,代码逻辑不清晰,难以理解且不利于后期维护,各层次模块之间职责不清晰等等。



二代MVP架构:


在2016年,Google 推出的基于 MVP 架构的 Demo 后,我们发现 MVP 架构能解决现在所面临过的很多问题。


MVP工作流程图:



  1. View接受用户的交互请求

  2. View将请求转交给Presenter

  3. Presenter操作Model进行数据库更新

  4. 数据更新之后,Model通知Presenter数据发生变化

  5. Presenter更新View的数据


MVP架构图如下:



  • View Layer: 负责绘制UI元素、与用户进行交互,对应于xml、Activity、Fragment、Adapter,包含一些自定义的 UI 组件

  • Model Layer: 负责检索、存储、操作数据,包括来自网络、数据库、磁盘文件和SharedPreferences的数据

  • Presenter Layer: 作为 View Layer 和 Module Layer 的之间的纽带,它从 Model 层中获取数据,然后调用 View 的接口去把数据显示在View上

  • Contract: 参照 Google 的 Demo 加入契约类 Contract 来统一管理 View 和 Presenter 的接口,使得某一功能模块的接口能更加直观的呈现出来,这样做是有利于后期维护的。


尽管这样,MVP模式也有不足之处,不然也不会推出MVVM了,缺点如下:


  • Presente层与View层是通过接口进行交互的,View层可能会有大量的接口,因为有可能好几个Activity都是去实现同一个View接口,那么所有用到的Activity都要去实现所有的方法(不管你是否用到),而且如果后面有些方法要删改,Presenter和Activity都要改动,比较麻烦;

  • MVP把Activity相当的一部分责任放到了Presenter来处理,复杂的业务同时也可能会导致P层太大,一旦业务逻辑越来越多,View定义的方法越来越多,会造成Activity和Fragment实现的方法越来越多,依然臃肿。


三代MVVM架构:


相对于 MVC 的历史来说,MVVM 是一个相当新的架构,MVVM模式不是四层,仍然是3层,分别是Model、View、ViewModel,MVVM 在使用当中,通常还会利用双向绑定技术,使得 Model 变化时,ViewModel 会自动更新,而 ViewModel 变化时,View 也会自动变化。所以,MVVM 模式有些时候又被称作:model-view-binder 模式。


MVVM 在实际使用中,确实能够使得 Model 层和 View 层解耦,但是如果你需要实现 MVVM 中的双向绑定的话,那么通常就需要引入更多复杂的框架来实现了。



  • View:视图层,采用XML文件进行界面的描述

  • Model:模型层,通过网络和本地数据库获取视图层所需数据

  • ViewModel:视图-模型层,负责View和Model之间的通信,以此分离视图和数据


工作流程:


  1. View中使用DataBinding的Command来绑定事件和响应事件,触发网络请求

  2. ViewModel进行分析处理,调用Model的方法去请求数据

  3. Model将收到的请求参数等信息封装,调用网络请求库

  4. 服务器将数据返回Retrofit等网络库,再返回到Model层中

  5. ViewModel在回调中收到返回的实体类对象

  6. 因为xml与实体类对象实现了双向绑定,实体类更新,使得UI更新


MVVM也存在着自己的一些缺点:


  • 数据绑定使得 Bug 很难被调试。你看到界面异常了,有可能是你 View 的代码有 Bug,也可能是 Model 的代码有问题。数据绑定使得一个位置的 Bug 被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了

  • 对于过大的项目,数据绑定需要花费更多的内存


某种意义上来说,我认为就是数据绑定使得 MVVM 变得复杂和难用了


四代架构MVP+组件化


前面讲的这三种android开发中常用的项目架构,不管是哪一种架构,它始终是一个单一结构体项目,各个模块之间还是以传统的包名来区分的,其各个模块还是强耦合在一的,自然而然组件化的方案就出现了,组件化有开发模式和发布模式之分,在开发模式下每个业务模块都是都是一个独立的apk,在发布模式打包的时候,每个业务模块都变成了一个个独立的组件library,这就完成了各个模块之间的彻底解耦。


今年开年以来公司就上了一个新项目Vcars,就采用了MVP + 组件化的解决方案,现在通过文字的形式把它记录下来,也是对这段时间工作的一个归纳总结。


Vcars组件化架构图:



  • 集成模式:所有的业务组件被“app壳工程”依赖,组成一个完整的APP;

  • 组件模式:可以独立开发业务组件,每一个业务组件就是一个APP;

  • app壳工程:负责管理各个业务组件,和打包apk,没有具体的业务功能;

  • 业务组件:根据公司具体业务而独立形成一个的工程;

  • 功能组件:提供开发APP的某些基础功能,例如打印日志、下拉刷新控件等;

  • Main组件:属于业务组件,指定APP启动页面、主界面;

  • Common组件:属于功能组件,支撑业务组件的基础,提供多数业务组件需要的功能


Vcars项目类图


Activity关系图:



Fragment类关系图:



BaseRefreshActivity类图:



BasePresenter类关系图:



BaseModel类关系图:



/  总结  /


整体来看MVVM 比MVC/MVP精简了很多,不仅仅简化了业务与界面的依赖,在MVVM中,View不知道Model的存在,ViewModel和Model也察觉不到View,这种低耦合模式可以使开发过程更加容易,提高应用的可重用性。


不管是MVC,MVP还是MVVM,他们都属于项目的编码架构,而组件化是整个工程的工程架构,它的主要意义在于,对原来以包来区分的各个模块进行完全的解耦,但是不管技术怎么怎么更新换代,但是永远不变的一个核心思想就是“调用更加方便、更加安全、代码之间的耦合度更低”,这是一个好的软件永远追求的目标。


推荐阅读:

时隔两年,趁着618,再度带你薅京东云的羊毛

这样使用Gradle可以神奇地打各种渠道包

原来一个App是这样启动起来的,一看就懂


欢迎关注我的公众号

学习技术或投稿



长按上图,识别图中二维码即可关注


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存